#include "libdwinport.h"
#include "gd32f30x.h"

struct dw_reg_s dw_regs[] = {
	{REG_TEMP_PAGE,REG_TEMP_ADDR,REG_TEMP_LENGTH,0},
	{REG_HUMI_PAGE,REG_HUMI_ADDR,REG_HUMI_LENGTH,0},
};

struct dw_var_s dw_vars[] = {
	{VAR_DISPAGE_ADDR,VAR_DISPAGE_LENGTH,0,0},
	{VAR_DEVNAME_ADDR,VAR_DEVNAME_LENGTH,0,0},
	{VAR_PARTNUM_ADDR,VAR_PARTNUM_LENGTH,0,0},
	{VAR_COLNUM_ADDR,VAR_COLNUM_LENGTH,0,0},
	{VAR_TEMP_ADDR,VAR_TEMP_LENGTH,0,0},
	{VAR_HUMI_ADDR,VAR_HUMI_LENGTH,0,0},
	{VAR_ACTIVE_ADDR,VAR_ACTIVE_LENGTH,0,0},
	{VAR_LOCK_ADDR,VAR_LOCK_LENGTH,0,0},
	{VAR_LIGHT_ADDR,VAR_LIGHT_LENGTH,0,0},
};

dwU16 dwUartIdx,dwUartCount;
dwU8 dwUartBuff[DW_UART_BUFF_SIZE];
dwU8 dwSendUartBuff[DW_UART_BUFF_SIZE];

dw_frame_reg_t pdfr 	= (dw_frame_reg_t)dwUartBuff;
dw_frame_var_t pdfv 	= (dw_frame_var_t)dwUartBuff;

dw_frame_reg_t psdfr	= (dw_frame_reg_t)dwSendUartBuff;
dw_frame_var_t psdfv	= (dw_frame_var_t)dwSendUartBuff;
dw_frame_var_wr_t psdfvwr	= (dw_frame_var_wr_t)dwSendUartBuff;

dwBOOL dwSysInit(dwVOID);

dwVOID	dwRecvChar(dwU8 data);
dwVOID	dwRecvFinish(dwVOID);
dwVOID  dwRecvProcess(dwVOID);

dwBOOL dw_reg_read(dwU8 page,dwU8 addr,dwU8 *value,dwU8 length);
dwBOOL dw_reg_write(dwU8 page,dwU8 addr,dwU8 *value,dwU8 length);
dwBOOL dw_var_read(dwU16 addr,dwU16 *value,dwU8 length);
dwBOOL dw_var_write(dwU16 addr,dwU16 *value,dwU8 length);

dwVOID	dwSendData(dwU8 *data,dwU8 length)
{
	dwU8 i;
	for(i=0;i<length;i++){
		while(!usart_flag_get(DW_UART,USART_FLAG_TBE));
		usart_data_transmit(DW_UART,data[i]);
		while(!usart_flag_get(DW_UART,USART_FLAG_TC));
	}
	dwUartCount = 0;
}

void DW_PortCfg(void)
{
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_AF);
	
	gpio_init(DW_MODULE_PORT,DW_URXD_MODE,GPIO_OSPEED_50MHZ,DW_URXD_PIN);
	gpio_init(DW_MODULE_PORT,DW_UTXD_MODE,GPIO_OSPEED_50MHZ,DW_UTXD_PIN);
	
	rcu_periph_clock_enable(DW_UART_RCU);
	usart_deinit(DW_UART);
	usart_baudrate_set(DW_UART,BUAD_RATE);
	usart_stop_bit_set(DW_UART,USART_STB_1BIT);
	usart_word_length_set(DW_UART,USART_WL_8BIT);
	usart_parity_config(DW_UART,USART_PM_NONE);
	usart_hardware_flow_rts_config(DW_UART, USART_RTS_DISABLE);
	usart_hardware_flow_cts_config(DW_UART, USART_CTS_DISABLE);
	usart_receive_config(DW_UART, USART_RECEIVE_ENABLE);
	usart_transmit_config(DW_UART, USART_TRANSMIT_ENABLE);
	usart_enable(DW_UART);
	usart_interrupt_enable(DW_UART,USART_INT_RBNE);
	nvic_irq_enable(DW_UART_IRQn,3,1);
}

dwBOOL dwInit(dwVOID)
{
	DW_PortCfg();
	return dwSysInit();
}

void USART2_IRQHandler(void){
	if(usart_interrupt_flag_get(DW_UART,USART_INT_FLAG_RBNE)==SET){
		dwRecvChar(usart_data_receive(DW_UART));
		usart_interrupt_flag_clear(DW_UART,USART_INT_FLAG_RBNE);
		usart_interrupt_enable(DW_UART,USART_INT_IDLE);
	}
	else if(usart_interrupt_flag_get(DW_UART,USART_INT_FLAG_IDLE)){
		dwRecvFinish();
		usart_interrupt_flag_clear(DW_UART,USART_INT_FLAG_IDLE);
		usart_interrupt_disable(DW_UART,USART_INT_IDLE);
	}
}



dwVOID	dwRecvChar(dwU8 data)
{
	dwUartBuff[dwUartIdx++] = data;
}

dwVOID	dwRecvFinish(dwVOID)
{
	dwUartCount = dwUartIdx;
	dwUartIdx = 0;
	dwRecvProcess();
}

dw_reg_t dw_regs_get(dwVOID)
{
	return dw_regs;
}

dw_var_t dw_vars_get(dwVOID)
{
	return dw_vars;
}

dwU8 dw_reg_num_get(dwVOID)
{
	return sizeof(dw_regs)/sizeof(struct dw_reg_s);
}

dwU8 dw_var_num_get(dwVOID)
{
	return sizeof(dw_vars)/sizeof(struct dw_var_s);
}

dwBOOL dwWaitRecv(dwVOID)
{
	dwU16	to = 0;
	dwUartCount = 0;
	while( to++ < 20000 && dwUartCount == 0){}
	if(dwUartCount > 0 ){
		return dwTRUE;
	}else{
		return dwFALSE;
	}
}




